﻿using System;
using System.Data;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using System.Net.Sockets;

using Server.Utils.JSON;
using System.Text;

namespace Server.Comm
{
    public delegate void ReceiveHandler(CommObj sender, JSONObject obj);

    public class CommObj
    {
        //event
        public event ReceiveHandler OnReceive = null;

        Socket m_handler = null;
        bool m_receiving = false;

        const int BufferSize = 1024;
        byte[] m_rbytes = new byte[BufferSize];
        string m_rdata = "";

        public CommObj(Socket handler)
        {
            m_handler = handler;
        }

        public void Close()
        {
            m_handler.Shutdown(SocketShutdown.Both);
            m_handler.Close();
        }

        public bool BeginReceive()
        {
            if (m_receiving)
            {
                return false;
            }

            m_receiving = true;
            m_handler.BeginReceive(m_rbytes, 0, BufferSize, 0, new AsyncCallback(ReceiveCallback), this);

            return true;
        }

        private void Received(IAsyncResult ar)
        {
            int bytesRead = m_handler.EndReceive(ar);

            if (bytesRead > 0)
            {
                m_rdata += Encoding.UTF8.GetString(m_rbytes);

                if (m_rdata.LastIndexOf("<EOF>") == -1)
                {
                    //not all data received
                    BeginReceive();
                }
                else
                {
                    //all data received                    
                    if (OnReceive != null)
                    {
                        JSONObject robj = JSONUtils.Decode(m_rdata);
                        m_rdata = "";

                        OnReceive(this, robj);
                    }

                    m_receiving = false;
                }
            }
        }

        private static void ReceiveCallback(IAsyncResult ar)
        {
            CommObj commObj = (CommObj)ar.AsyncState;
            commObj.Received(ar);
        }

    }
}